package cn.nextProject.service;

import cn.nextProject.Utils.CommonUtils;
import cn.nextProject.entity.flowable.TaskDTO;
import lombok.extern.slf4j.Slf4j;
import org.flowable.bpmn.model.BpmnModel;
import org.flowable.bpmn.model.Process;
import org.flowable.bpmn.model.StartEvent;
import org.flowable.common.engine.api.FlowableObjectNotFoundException;
import org.flowable.engine.FormService;
import org.flowable.engine.ProcessEngine;
import org.flowable.engine.RepositoryService;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.repository.ProcessDefinition;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.task.api.Task;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import sun.text.resources.FormatData;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 流程任务服务
 */
@Slf4j
@Service
public class TaskService {

    @Autowired
    private RuntimeService runtimeService;
    @Autowired
    private ProcessEngine processEngine;

    @Autowired
    private RepositoryService repositoryService;

    @Autowired
    private org.flowable.engine.TaskService taskService;
    @Autowired
    private FormService formService;

    /**
     * 获取用户的所有流程实例（任务）
     * @param username
     * @return
     */
    public List<Task> getMyTasks(String username){

        // 查询该用户发起的流程实例列表
        List<ProcessInstance> processInstances = runtimeService.createProcessInstanceQuery()
                .startedBy(username)  // 关键：按发起人过滤
                .orderByStartTime().desc()
                .list();

        List<Task> userTasks = new ArrayList<>();
        for (ProcessInstance instance : processInstances) {
            List<Task> tasks = taskService.createTaskQuery()
                    .processInstanceId(instance.getId())  // 按流程实例ID过滤
                    .list();
            userTasks.addAll(tasks);
        }

        return userTasks;
    }

    public Map<Integer,Object> startTask(String processDefinitionId, Map<String,Object> variables){
        String username = CommonUtils.getToken();

        Map<Integer,Object> returnMap = new HashMap<>();

        //1.获取流程定义
        ProcessDefinition processDefinition = repositoryService
                .createProcessDefinitionQuery()
                .processDefinitionId(processDefinitionId)
                .singleResult();

        if (processDefinition == null) {
            returnMap.put(0,"未找到对应的流程定义");
            return returnMap;
        }

        //2.设置流程变量
//        Map<String, Object> variables = new HashMap<>();
        // 将表单数据转换为流程变量
//        variables.putAll(formData);

        //3.设置流程发起人
        variables.put("sqr", username);

        Map<String,String> formData = new HashMap<>();
        Iterator<Map.Entry<String, Object>> iterator = variables.entrySet().iterator();
        while (iterator.hasNext()) {
            Map.Entry<String, Object> entry = iterator.next();
            String key = entry.getKey();
            String value = (String) entry.getValue();
            formData.put(key,value);
        }

        try {
            ProcessInstance processInstance = formService.submitStartFormData(processDefinitionId, formData);
        } catch (FlowableObjectNotFoundException e) {
            log.error(processDefinitionId + "流程定义不存在:{}",e);
            returnMap.put(0,"流程定义不存在");
            return returnMap;
        }
        returnMap.put(1,"流程启动成功");
        return returnMap;
    }


    /**
     * 待办任务查询
     * @param username
     */
    public List<TaskDTO> findTask(String username){
        // 任务查询这块我们可以通过 TaskService 来实现
        org.flowable.engine.TaskService taskService = processEngine.getTaskService();
        List<Task> tasks = taskService.createTaskQuery()
                .taskAssignee(username)
                .orderByTaskCreateTime().asc()
                .orderByTaskPriority().desc()
                .list();
        // 查询的其实就是 act_ru_task 中的记录
        // tasks是懒加载的，所以需要主动加载变量
        return tasks.stream().map(task -> {
            TaskDTO dto = new TaskDTO();
            dto.setId(task.getId());
            dto.setName(task.getName());
            // 主动加载变量，避免懒加载
            dto.setVariables(taskService.getVariables(task.getId()));
            dto.setProcessInstanceId(task.getProcessInstanceId());
            return dto;
        }).collect(Collectors.toList());
    }

    /**
     * 完成任务审批
     */
    public int completeTask(String taskId){
        try{
            org.flowable.engine.TaskService taskService = processEngine.getTaskService();

            taskService.complete(taskId); // 通过complete方法完成审批
        }catch (Exception e){
            log.error("完成任务失败:{}",e);
            return 0;
        }

        return 1;
    }

}
